home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
threads
/
ThreadsMain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-29
|
15KB
|
540 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
endcopyright */
/*
* ThreadsMain.c
*
* Demers, November 30, 1990 11:08:16 am PST
* Boehm, May 29, 1991 5:02:08 pm PDT
*
* Startup code for Xerox Runtime threads package.
*/
#include "xr/BasicTypes.h"
#include "xr/Threads.h"
#include "xr/ThreadsBackdoor.h"
#include "xr/ThreadsMsg.h"
#include "xr/ThreadsMsgPrivate.h"
#include "xr/CommandLoop.h"
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <strings.h>
/*
* Startup configuration and arg processing ...
*/
extern char XR_threadsVersion[];
unsigned XR_maxVPs = 1;
unsigned XR_maxSlaveIOPs = 0;
unsigned XR_maxStdIOPs = 1;
unsigned XR_maxStrIOPs = 1;
unsigned XR_maxIOPs = 0;
unsigned XR_maxThreads = 40;
unsigned XR_maxSysMem = XR_MAX_SYS_MEM;
int XR_maxThreadStackGroups = 0;
struct XR_ThreadStackGroupRep
XR_threadStackGroups[XR_MAX_THREAD_STACK_GROUPS];
int XR_threadStackBytes = XR_THREAD_STACK_BYTES;
int XR_argc;
char **XR_argv;
static void XR_Usage();
static bool XR_helloWorldPrinted = FALSE;
static void
XR_PrintHelloWorld(level)
int level;
{
if( XR_helloWorldPrinted ) return;
if( !XR_VERBOSE(level) ) return;
XR_helloWorldPrinted = TRUE;
XR_VMsg "\n\nXerox Portable Common Runtime (PCR).\n");
XR_VMsg "Version %s\n", &(XR_threadsVersion[0]));
XR_VMsg " %s (pid %d)\n\n", XR_argv[0], getpid() );
}
void
XR_Configure ()
{
int i;
int nofile;
int assignedIOPs = 0;
char *tmpStr;
nofile = getdtablesize();
for( i = 0; i < nofile; i++ ) {
if( (i != XR_stdInFD) && (i != XR_stdOutFD) )
(void) close(i);
}
XR_NormalVMsg " -vp %d", XR_maxVPs);
XR_NormalVMsg " -slaveiop %d", XR_maxSlaveIOPs);
assignedIOPs += XR_maxSlaveIOPs;
XR_NormalVMsg " -striop %d", XR_maxStrIOPs);
assignedIOPs += XR_maxStrIOPs;
XR_NormalVMsg " -stdiop %d", XR_maxStdIOPs);
assignedIOPs += XR_maxStdIOPs;
XR_maxIOPs = assignedIOPs;
if( XR_maxIOPs > XR_MAX_IOPS ) XR_Usage("too many IOPs total");
if( XR_maxThreads <= XR_maxVPs ) XR_Usage("-thread: too small");
if( XR_maxThreadStackGroups == 0 ) {
XR_threadStackGroups[0].tsg_numThreads = XR_maxThreads;
XR_threadStackGroups[0].tsg_stackBytes = XR_threadStackBytes;
XR_maxThreadStackGroups = 1;
}
XR_NormalVMsg "\n\t-thread ");
for( i = 0; i < XR_maxThreadStackGroups; i++ ) {
XR_NormalVMsg "%d %d",
XR_threadStackGroups[i].tsg_numThreads,
XR_threadStackGroups[i].tsg_stackBytes );
}
XR_NormalVMsg " -stack %d", XR_threadStackBytes);
if( XR_threadStackBytes >
XR_threadStackGroups[XR_maxThreadStackGroups-1].tsg_stackBytes )
XR_Usage("-stack: too big");
XR_NormalVMsg " -mem %d", XR_maxSysMem);
if( (tmpStr = XR_GetShmArg()) == NIL ) tmpStr = "";
XR_NormalVMsg " -shmtype %s %s", XR_GetShmType(), tmpStr);
XR_NormalVMsg "\n\t-tmpdir %s", XR_GetTmpDirectory());
if( (tmpStr = XR_GetDBXScriptName()) != NIL ) {
XR_NormalVMsg "\n\t-dbxscript %s", tmpStr);
} else {
XR_NormalVMsg "\n\t-nodbxscript");
}
if( (tmpStr = XR_GetPCRFileName()) != NIL ) {
XR_NormalVMsg "\n\t-dyload %s", tmpStr);
} else {
XR_NormalVMsg "\n\t-nodyload");
}
XR_NormalVMsg "\n\n");
}
static void
XR_ParseSwitches(argc, argv, message, usage)
int argc;
char ** argv;
void (*message)(/* char *msg, ... */);
void (*usage)(/* char *msg */);
{
int i;
# define ECHO (*message)(
# define USAGE (*usage)(
# define AEQ(s) (strcmpcase(a,(s)) == 0)
i = 0;
while( i < argc ) {
char *a = argv[i++];
int intarg;
unsigned cardarg;
char *strarg;
char *strarg2;
char *errmsg;
int defaultVerbosity = (-1);
if( AEQ("-dbx") || AEQ("-dbxscript") ) {
if( (i < argc) && (argv[i][0] != '-') ) {
strarg = argv[i++];
ECHO " %s %s\n", a, strarg);
} else {
strarg = XR_DEFAULT_DBX_SCRIPT_NAME;
ECHO " %s\n", a);
}
if( XR_SetDBXScriptName(strarg) != 0 )
USAGE "%s: bad name", a);
continue;
} else if( AEQ("-nodbx") || AEQ("-nodbxscript") ) {
(void) XR_SetDBXScriptName(NIL);
continue;
}
if( AEQ("-dyload") ) {
if( (i < argc) && (argv[i][0] != '-') ) {
strarg = argv[i++];
ECHO " %s %s\n", a, strarg);
} else {
strarg = XR_argv[0];
ECHO " %s\n", a);
}
if( XR_SetPCRFileName(strarg) != 0 )
USAGE "%s: bad symbol file name", a);
continue;
} else if( AEQ("-nodyload") ) {
(void) XR_SetPCRFileName(NIL);
continue;
}
if( AEQ("-mem") ) {
if( i >= argc ) XR_Usage("%s: missing arg", a);
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %s %d\n", a, cardarg);
if( cardarg < XR_MAX_SYS_MEM ) cardarg = XR_MAX_SYS_MEM;
XR_maxSysMem = cardarg;
continue;
}
if( AEQ("-v") || AEQ("-verbose") ) {
defaultVerbosity = XR_VERBOSITY_VERBOSE;
} else if( AEQ("-quiet") ) {
defaultVerbosity = XR_VERBOSITY_QUIET;
} else if( AEQ("-msgs") ) {
defaultVerbosity = XR_VERBOSITY_NORMAL;
}
if( defaultVerbosity >= 0 ) {
/* funny structure so "-quiet" doesn't echo */
if( (i < argc) && ((argv[i])[0] != '-') ) {
if( strcmpcase(argv[i], "verbose") == 0 ) {
intarg = XR_VERBOSITY_VERBOSE;
} else if( strcmpcase(argv[i], "quiet") == 0 ) {
intarg = XR_VERBOSITY_QUIET;
} else if( strcmpcase(argv[i], "normal") == 0 ) {
intarg = XR_VERBOSITY_NORMAL;
} else {
intarg = atoi(argv[i]);
}
if( intarg < 0 ) USAGE "%s: bad level\n", a);
XR_verbosity = intarg;
ECHO " %s %s\n", a, argv[i]);
i += 1;
} else {
XR_verbosity = defaultVerbosity;
ECHO " %s\n", a);
}
continue;
}
if( AEQ("-shmtype") ) {
if (i >= argc) USAGE "%s: missing arg", a);
strarg = argv[i++];
strarg2 = NIL;
if( (i < argc) && (argv[i][0] != '-') ) strarg2 = argv[i++];
ECHO " %s %s %s\n", a, strarg, (strarg2 ? strarg2 : "") );
if( (errmsg = XR_SetShmType(strarg)) != NIL ) {
USAGE "bad shmtype (%s)", errmsg);
}
if( strarg2 != NIL ) {
if( (errmsg = XR_SetShmArg(strarg2)) != NIL ) {
USAGE "bad shm arg (%s)", errmsg);
}
}
continue;
}
if( AEQ("-slave") || AEQ("-slaveiop") ) {
if( i >= argc ) XR_Usage("%s: missing arg", a);
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %s %d\n", a, cardarg);
if( cardarg > XR_MAX_SLAVEIOPS ) USAGE "%s: too big", a);
XR_maxSlaveIOPs = cardarg;
continue;
}
if( AEQ("-stack") || AEQ("-stackbytes") ) {
if( i >= argc ) XR_Usage("%s: missing arg", a);
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %s %d\n", a, cardarg);
if( cardarg < XR_MIN_THREAD_STACK_BYTES )
USAGE "%s: too small", a);
if( cardarg > XR_MAX_THREAD_STACK_BYTES )
USAGE "%s: too big", a);
XR_threadStackBytes = XR_ComputeAddress( cardarg, 0, XR_ROUND_UP );
continue;
}
if( AEQ("-std") || AEQ("-stdiop") ) {
if( i >= argc ) USAGE "%s: missing arg", a);
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %s %d\n", a, cardarg);
if( cardarg == 0 )
USAGE "%s: too small", a);
XR_maxStdIOPs = cardarg;
continue;
}
if( AEQ("-str") || AEQ("-striop") ) {
if( i >= argc ) XR_Usage("%s: missing arg", a);
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %s %d\n", a, cardarg);
if( cardarg == 0 )
USAGE "%s: too small", a);
XR_maxStrIOPs = cardarg;
continue;
}
if( AEQ("-thread") ) {
XR_maxThreads = 0;
XR_maxThreadStackGroups = 0;
ECHO " %s ", a);
for(;;) {
if( (i >= argc) || (argv[i][0] == '-') ) {
if( XR_maxThreads == 0 ) {
USAGE "%s: missing count arg", a);
} else {
break;
}
}
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %d", cardarg);
if( cardarg == 0 )
USAGE "%s: too small", a);
if( (i >= argc) || (argv[i][0] == '-') ) {
if( XR_maxThreads == 0 ) {
XR_maxThreads = cardarg;
break;
} else {
USAGE "-thread: missing stacksize arg");
}
}
XR_maxThreads += cardarg;
if( XR_maxThreadStackGroups >= XR_MAX_THREAD_STACK_GROUPS )
USAGE "%s: too many thread stack groups", a);
XR_threadStackGroups[XR_maxThreadStackGroups].tsg_numThreads =
cardarg;
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %d", cardarg);
if( cardarg < XR_MIN_THREAD_STACK_BYTES )
USAGE "%s: stacksize too small", a);
cardarg = XR_RoundToPage(cardarg, XR_ROUND_UP);
if( cardarg > XR_MAX_THREAD_STACK_BYTES )
USAGE "%s: stacksize too big", a);
if( (XR_maxThreadStackGroups > 0) && (cardarg <
XR_threadStackGroups[XR_maxThreadStackGroups-1] .
tsg_stackBytes) ) {
USAGE "%s: stack sizes not increasing", a);
}
XR_threadStackGroups[XR_maxThreadStackGroups].tsg_stackBytes =
cardarg;
XR_maxThreadStackGroups += 1;
}
if( XR_maxThreads > XR_MAX_THREADS )
USAGE "%s: too many threads", a);
continue;
}
if( AEQ("-tmp") || AEQ("-tmpdir") ) {
if( i >= argc ) USAGE "%s: missing arg", a);
strarg = argv[i++];
ECHO " %s %s\n", a, strarg);
if( XR_SetTmpDirectory(strarg) != 0 )
USAGE "%s: illegal directory name", a);
continue;
}
if( AEQ("-vp") ) {
if( i >= argc ) USAGE "%s: missing arg", a);
cardarg = (unsigned) atoi(argv[i++]);
ECHO " %s %d\n", a, cardarg);
if( cardarg == 0 )
USAGE "%s: too small", a);
if( cardarg > XR_MAX_VPS )
USAGE "%s: too big", a);
XR_maxVPs = cardarg;
continue;
}
if( AEQ("--") ) {
break;
}
if( AEQ("-") ) {
USAGE "", 0);
}
if( a[0] == '-' ) {
ECHO "%s: ", a);
USAGE "bad arg: %s", a );
}
}
}
#undef ECHO
static void
XR_ArgsMsg(fmt, x1, x2, x3, x4)
char *fmt;
XR_Pointer x1, x2, x3, x4;
{
XR_LogVMsg fmt, x1, x2, x3, x4);
}
static void
XR_Usage (fmt, x)
char *fmt;
unsigned x;
{
# define PUT XR_FPrintF(XR_MSG_STDOUT,
if( ! XR_VERBOSE(XR_VERBOSITY_ERROR) ) return;
PUT "\n");
PUT "%s: ", XR_argv[0]);
PUT fmt, x);
PUT "\nUsage: %s ", XR_argv[0]);
PUT "\t[-quiet [number]] [-verbose [number]]\n");
PUT "[-vp number] [-slaveiop number] [-stdiop number] [-striop number]\n");
PUT "\t[-thread number stk ...] [-mem bytes] [-stack bytes]\n");
PUT "\t[-shmtype type [arg]]\n");
PUT "\t[-dyload [filename]] [-nodyload]\n");
PUT "\t[-dbxscript [filename]] [-nodbxscript]\n");
PUT "\t[-tmpdir [filename]]\n");
PUT "\t-- (args for after startup)\n");
_exit(-1);
}
#undef PUT
static void
XR_PkgMsg(fmt, x1, x2, x3, x4)
char *fmt;
XR_Pointer x1, x2, x3, x4;
{
XR_VerboseVMsg fmt, x1, x2, x3, x4);
}
static void
XR_PkgUsage(fmt, x)
char *fmt;
unsigned x;
{
XR_ErrorVMsg "\n%s: fatal error in setup: ", XR_argv[0]);
XR_ErrorVMsg fmt, x);
XR_ErrorVMsg "\n");
_exit(-1);
}
static void
XR_IncludeTheseProcsInPCR()
{
strcasecmp();
strncasecmp();
}
static int
XR_FindExecutableFileUsingSearchRules(buf, bufLen, shortName)
char *buf;
int bufLen;
char *shortName;
{
char *pathEnv;
char *p, *q, *cwd;
int pathLen, shortNameLen, cwdLen;
cwd = (char *)(getenv("PWD"));
cwdLen = ((cwd) ? strlen(cwd) : 0);
if( shortName[0] == '/' ) {
pathEnv = "/";
} else if( strchr(shortName, '/') != NIL ) {
if( cwdLen == 0 ) return (-1);
pathEnv = cwd;
} else {
if( (pathEnv = (char *)(getenv("PATH"))) == NIL ) return (-1);
}
shortNameLen = strlen(shortName);
q = pathEnv;
for(;;) {
p = q;
while( *p == ':' ) p++;
if( *p == 0 ) return (-1);
q = p;
while( (*q != ':') && (*q != 0) ) q++;
pathLen = (q - p);
if( p[0] == '/' ) {
if( pathLen >= bufLen ) continue;
(void)bcopy(p, buf, pathLen);
} else {
if( cwdLen == 0 ) continue;
if( p[0] == '.' ) { p++; pathLen--; }
if( (cwdLen + 1 + pathLen) >= bufLen ) continue;
(void)bcopy(cwd, buf, cwdLen);
buf[cwdLen] = '/';
if( pathLen > 0 ) (void)bcopy(p, &(buf[cwdLen+1]), pathLen);
pathLen += (cwdLen+1);
}
if( (pathLen + 1 + shortNameLen) >= bufLen ) continue;
buf[pathLen] = '/';
strcpy(buf+pathLen+1, shortName);
if( access(buf, X_OK) == 0 ) return 0;
}
/*NOTREACHED*/
}
extern void XR_InitAndRun();
void
main(argc, argv)
int argc;
char ** argv;
{
int pkgArgC;
char **pkgArgV;
int ans;
char fnBuf[1024];
XR_argc = argc;
XR_argv = argv;
if( argc < 1 ) XR_Panic("main argc == 0");
ans = XR_FindExecutableFileUsingSearchRules(
fnBuf, (sizeof fnBuf), argv[0] );
if( ans == 0 ) ans = XR_SetPCRFileName(fnBuf);
if( ans != 0 ) XR_Usage("bad PCR name", NIL);
XR_GetPackageDefaultArgs(&pkgArgC, &pkgArgV);
if( pkgArgC > 0 ) {
XR_PrintHelloWorld(XR_VERBOSITY_VERBOSE);
XR_ParseSwitches(pkgArgC, pkgArgV, XR_PkgMsg, XR_PkgUsage);
}
if( argc > 1 ) {
XR_PrintHelloWorld(XR_VERBOSITY_LOG);
XR_ParseSwitches(argc-1, argv+1, XR_ArgsMsg, XR_Usage);
}
XR_PrintHelloWorld(XR_VERBOSITY_NORMAL);
XR_Configure();
XR_InitAndRun();
/* no return */
_exit(0);
}